package com.filetransfer.controller;

import com.filetransfer.model.dto.FileTransferDTO;
import com.filetransfer.model.vo.ApiResult;
import com.filetransfer.service.FileTransferService;
import com.filetransfer.util.FileUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

/**
 * 文件传输控制器
 */
@Slf4j
@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
public class FileTransferController {

    private final FileTransferService fileTransferService;
    
    /**
     * 创建文件传输记录
     */
    @PostMapping("/create")
    public ApiResult<FileTransferDTO> createTransfer(@RequestBody FileTransferDTO fileTransferDTO) {
        Long id = fileTransferService.createFileTransfer(fileTransferDTO);
        return ApiResult.success(fileTransferService.getByTransferKey(fileTransferDTO.getTransferKey()));
    }
    
    /**
     * 通过密钥获取文件传输记录
     */
    @GetMapping("/key/{transferKey}")
    public ApiResult<FileTransferDTO> getByTransferKey(@PathVariable String transferKey) {
        FileTransferDTO fileTransferDTO = fileTransferService.getByTransferKey(transferKey);
        if (fileTransferDTO != null) {
            return ApiResult.success(fileTransferDTO);
        } else {
            return ApiResult.error("文件传输记录不存在");
        }
    }
    
    /**
     * 更新文件传输状态
     */
    @PutMapping("/status")
    public ApiResult<Boolean> updateStatus(@RequestParam Long id, 
                                          @RequestParam Integer status,
                                          @RequestParam(required = false) String receiverId,
                                          @RequestParam(required = false) String receiverName) {
        if (receiverId != null && receiverName != null) {
            // 更新状态和接收者信息
            boolean result = fileTransferService.updateStatusAndReceiver(id, status, receiverId, receiverName);
            return ApiResult.success(result);
        } else {
            // 仅更新状态
            boolean result = fileTransferService.updateStatus(id, status);
            return ApiResult.success(result);
        }
    }
    
    /**
     * 获取发送的文件传输记录
     */
    @GetMapping("/sent")
    public ApiResult<List<FileTransferDTO>> getSentFiles(@RequestParam String senderId) {
        List<FileTransferDTO> files = fileTransferService.getSentFileTransfers(senderId);
        return ApiResult.success(files);
    }
    
    /**
     * 获取接收的文件传输记录
     */
    @GetMapping("/received")
    public ApiResult<List<FileTransferDTO>> getReceivedFiles(@RequestParam String receiverId) {
        List<FileTransferDTO> files = fileTransferService.getReceivedFileTransfers(receiverId);
        return ApiResult.success(files);
    }
    
    /**
     * 获取两个设备之间的文件传输记录
     */
    @GetMapping("/between")
    public ApiResult<List<FileTransferDTO>> getFilesBetween(
            @RequestParam String deviceId1,
            @RequestParam String deviceId2) {
        List<FileTransferDTO> files = fileTransferService.getFileTransfersBetween(deviceId1, deviceId2);
        return ApiResult.success(files);
    }
    
    /**
     * 下载文件
     */
    @GetMapping("/download/{id}")
    public void downloadFile(@PathVariable Long id, HttpServletResponse response) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        
        try {
            // 获取文件传输记录
            FileTransferDTO fileTransfer = fileTransferService.getById(id);
            if (fileTransfer == null) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            
            // 获取文件路径
            File file = new File(fileTransfer.getFilePath());
            if (!file.exists() || !file.canRead()) {
                log.error("文件不存在或无法读取: {}", fileTransfer.getFilePath());
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            
            // 获取文件名
            String filename = fileTransfer.getFileName();
            
            // URL编码文件名，解决中文问题
            String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString())
                .replaceAll("\\+", "%20");
            
            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFilename + "\"");
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFilename);
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "0");
            response.setContentLengthLong(file.length());
            
            log.info("准备下载文件: {}, 大小: {}", filename, file.length());
            
            // 流式传输文件
            inputStream = new BufferedInputStream(new FileInputStream(file));
            outputStream = response.getOutputStream();
            
            byte[] buffer = new byte[4096];
            int bytesRead;
            
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
                outputStream.flush();
            }
            
            log.info("文件: {} 下载完成", filename);
            
        } catch (Exception e) {
            log.error("文件下载失败: {}", e.getMessage(), e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } finally {
            // 关闭流
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                log.error("关闭流失败: {}", e.getMessage(), e);
            }
        }
    }
    
    /**
     * 上传文件
     */
    @PostMapping("/upload")
    public ApiResult<String> uploadFile(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return ApiResult.error("文件为空");
        }
        
        try {
            String filePath = FileUtil.saveFile(file);
            return ApiResult.success(filePath);
        } catch (IOException e) {
            log.error("文件上传失败: {}", e.getMessage());
            return ApiResult.error("文件上传失败: " + e.getMessage());
        }
    }
} 